From e6d24f4c159320d59016598ed305677d64397c03 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 20 Mar 2018 04:33:58 +0100 Subject: [PATCH] snapshot: Make gtk_snapshot_append_node() take care of offset Push an offset node when append_node is called. That resets the offset. --- gtk/gskpango.c | 4 +- gtk/gtkcssshadowvalue.c | 6 +- gtk/gtkoverlay.c | 2 - gtk/gtkrenderborder.c | 3 +- gtk/gtksnapshot.c | 139 +++++++++++++++++++++++++++++++++------ gtk/gtksnapshotprivate.h | 3 + gtk/gtkstack.c | 31 +++------ 7 files changed, 140 insertions(+), 48 deletions(-) diff --git a/gtk/gskpango.c b/gtk/gskpango.c index e293759d2d..1b84c71357 100644 --- a/gtk/gskpango.c +++ b/gtk/gskpango.c @@ -21,7 +21,7 @@ #include "gsk/gsk.h" #include "gskpango.h" -#include "gtksnapshot.h" +#include "gtksnapshotprivate.h" #include @@ -162,7 +162,7 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer, gsk_render_node_set_name (node, name); } - gtk_snapshot_append_node (crenderer->snapshot, node); + gtk_snapshot_append_node_internal (crenderer->snapshot, node); gsk_render_node_unref (node); } diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c index 9fee5abf15..f1198fff29 100644 --- a/gtk/gtkcssshadowvalue.c +++ b/gtk/gtkcssshadowvalue.c @@ -24,7 +24,7 @@ #include "gtkcsscolorvalueprivate.h" #include "gtkcssnumbervalueprivate.h" #include "gtkcssrgbavalueprivate.h" -#include "gtksnapshot.h" +#include "gtksnapshotprivate.h" #include "gtkstylecontextprivate.h" #include "gtkpango.h" @@ -1057,7 +1057,7 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow, _gtk_css_number_value_get (shadow->radius, 0)); if (gtk_snapshot_get_record_names (snapshot)) gsk_render_node_set_name (node, "Outset Shadow"); - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } @@ -1088,7 +1088,7 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow, _gtk_css_number_value_get (shadow->radius, 0)); if (gtk_snapshot_get_record_names (snapshot)) gsk_render_node_set_name (node, "Inset Shadow"); - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } diff --git a/gtk/gtkoverlay.c b/gtk/gtkoverlay.c index 2e8f4dc2f9..54230b6879 100644 --- a/gtk/gtkoverlay.c +++ b/gtk/gtkoverlay.c @@ -655,7 +655,6 @@ gtk_overlay_snapshot (GtkWidget *widget, GtkAllocation main_alloc; cairo_region_t *clip = NULL; int i; - graphene_matrix_t translate; main_widget = gtk_bin_get_child (GTK_BIN (widget)); gtk_widget_get_allocation (widget, &main_alloc); @@ -682,7 +681,6 @@ gtk_overlay_snapshot (GtkWidget *widget, gtk_widget_snapshot (main_widget, child_snapshot); gtk_snapshot_offset (child_snapshot, -main_alloc.x, -main_alloc.y); main_widget_node = gtk_snapshot_free_to_node (child_snapshot); - graphene_matrix_init_translate (&translate, &GRAPHENE_POINT3D_INIT (main_alloc.x,main_alloc.y, 0)); } gtk_widget_get_allocation (child, &alloc); diff --git a/gtk/gtkrenderborder.c b/gtk/gtkrenderborder.c index 132a30c21a..540a66e2d8 100644 --- a/gtk/gtkrenderborder.c +++ b/gtk/gtkrenderborder.c @@ -35,6 +35,7 @@ #include "gtkcssstyleprivate.h" #include "gtkhslaprivate.h" #include "gtkroundedboxprivate.h" +#include "gtksnapshotprivate.h" #include "gsk/gskroundedrectprivate.h" @@ -440,7 +441,7 @@ snapshot_frame_fill (GtkSnapshot *snapshot, node = gsk_border_node_new (&offset_outline, border_width, colors); if (gtk_snapshot_get_record_names (snapshot)) gsk_render_node_set_name (node, "Border"); - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index cc8bd80b50..3299c4ccdc 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -336,6 +336,98 @@ gtk_snapshot_push_transform (GtkSnapshot *snapshot, graphene_matrix_multiply (transform, &offset, &state->data.transform.transform); } +static GskRenderNode * +gtk_snapshot_collect_offset (GtkSnapshot *snapshot, + GtkSnapshotState *state, + GskRenderNode **nodes, + guint n_nodes, + const char *name) +{ + GskRenderNode *node, *offset_node; + GtkSnapshotState *previous_state; + + node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name); + if (node == NULL) + return NULL; + + previous_state = gtk_snapshot_get_previous_state (snapshot); + if (previous_state->translate_x == 0.0 && + previous_state->translate_y == 0.0) + return node; + + offset_node = gsk_offset_node_new (node, + previous_state->translate_x, + previous_state->translate_y); + if (name) + gsk_render_node_set_name (offset_node, name); + + gsk_render_node_unref (node); + + return offset_node; +} + +static void +gtk_snapshot_push_offset (GtkSnapshot *snapshot, + const char *name, + ...) G_GNUC_PRINTF(2, 3); +static void +gtk_snapshot_push_offset (GtkSnapshot *snapshot, + const char *name, + ...) +{ + GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot); + char *str; + cairo_region_t *offset_clip; + + if (name && snapshot->record_names) + { + va_list args; + + va_start (args, name); + str = g_strdup_vprintf (name, args); + va_end (args); + } + else + str = NULL; + + if (state->clip_region) + { + offset_clip = cairo_region_copy (state->clip_region); + if (state->translate_x != floor (state->translate_x)) + { + cairo_region_translate (offset_clip, -1, 0); + cairo_region_union (offset_clip, state->clip_region); + if (state->translate_y != floor (state->translate_y)) + { + cairo_region_t *tmp = cairo_region_copy (offset_clip); + cairo_region_translate (offset_clip, 0, -1); + cairo_region_union (offset_clip, tmp); + cairo_region_destroy (tmp); + } + } + else if (state->translate_y != floor (state->translate_y)) + { + cairo_region_translate (offset_clip, 0, -1); + cairo_region_union (offset_clip, state->clip_region); + } + cairo_region_translate (offset_clip, + - floor (state->translate_x), + - floor (state->translate_y)); + + } + else + { + offset_clip = NULL; + } + state = gtk_snapshot_push_state (snapshot, + str, + offset_clip, + 0, 0, + gtk_snapshot_collect_offset); + if (offset_clip) + cairo_region_destroy (offset_clip); +} + static GskRenderNode * gtk_snapshot_collect_opacity (GtkSnapshot *snapshot, GtkSnapshotState *state, @@ -1191,7 +1283,7 @@ gtk_snapshot_pop (GtkSnapshot *snapshot) node = gtk_snapshot_pop_internal (snapshot); if (node) { - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } } @@ -1261,6 +1353,25 @@ gtk_snapshot_get_offset (GtkSnapshot *snapshot, *y = current_state->translate_y; } +void +gtk_snapshot_append_node_internal (GtkSnapshot *snapshot, + GskRenderNode *node) +{ + GtkSnapshotState *current_state; + + current_state = gtk_snapshot_get_current_state (snapshot); + + if (current_state) + { + g_ptr_array_add (snapshot->nodes, gsk_render_node_ref (node)); + current_state->n_nodes ++; + } + else + { + g_critical ("Tried appending a node to an already finished snapshot."); + } +} + /** * gtk_snapshot_append_node: * @snapshot: a #GtkSnapshot @@ -1275,22 +1386,12 @@ void gtk_snapshot_append_node (GtkSnapshot *snapshot, GskRenderNode *node) { - GtkSnapshotState *current_state; - g_return_if_fail (snapshot != NULL); g_return_if_fail (GSK_IS_RENDER_NODE (node)); - current_state = gtk_snapshot_get_current_state (snapshot); - - if (current_state) - { - g_ptr_array_add (snapshot->nodes, gsk_render_node_ref (node)); - current_state->n_nodes ++; - } - else - { - g_critical ("Tried appending a node to an already finished snapshot."); - } + gtk_snapshot_push_offset (snapshot, "OffsetReset"); + gtk_snapshot_append_node_internal (snapshot, node); + gtk_snapshot_pop (snapshot); } /** @@ -1351,7 +1452,7 @@ gtk_snapshot_append_cairo (GtkSnapshot *snapshot, g_free (str); } - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); cr = gsk_cairo_node_get_draw_context (node); @@ -1404,7 +1505,7 @@ gtk_snapshot_append_texture (GtkSnapshot *snapshot, g_free (str); } - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } @@ -1469,7 +1570,7 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot, g_free (str); } - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } @@ -1709,7 +1810,7 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot *snapshot, g_free (str); } - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } @@ -1787,6 +1888,6 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot *snapshot, g_free (str); } - gtk_snapshot_append_node (snapshot, node); + gtk_snapshot_append_node_internal (snapshot, node); gsk_render_node_unref (node); } diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h index 920da7917d..b1501f6307 100644 --- a/gtk/gtksnapshotprivate.h +++ b/gtk/gtksnapshotprivate.h @@ -97,6 +97,9 @@ struct _GtkSnapshotClass { GObjectClass parent_class; /* it's really GdkSnapshotClass, but don't tell anyone! */ }; +void gtk_snapshot_append_node_internal (GtkSnapshot *snapshot, + GskRenderNode *node); + G_END_DECLS #endif /* __GTK_SNAPSHOT_PRIVATE_H__ */ diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c index a5c46ba2cf..0b05f42352 100644 --- a/gtk/gtkstack.c +++ b/gtk/gtkstack.c @@ -1790,18 +1790,13 @@ gtk_stack_snapshot_crossfade (GtkWidget *widget, if (priv->last_visible_node) { - graphene_matrix_t translate; - - graphene_matrix_init_translate (&translate, - &GRAPHENE_POINT3D_INIT ( - priv->last_visible_surface_allocation.x, - priv->last_visible_surface_allocation.y, - 0) - ); - - gtk_snapshot_push_transform (snapshot, &translate, "CrossFadeStart"); + gtk_snapshot_offset (snapshot, + priv->last_visible_surface_allocation.x, + priv->last_visible_surface_allocation.y); gtk_snapshot_append_node (snapshot, priv->last_visible_node); - gtk_snapshot_pop (snapshot); + gtk_snapshot_offset (snapshot, + -priv->last_visible_surface_allocation.x, + -priv->last_visible_surface_allocation.y); } gtk_snapshot_pop (snapshot); @@ -1865,13 +1860,9 @@ gtk_stack_snapshot_under (GtkWidget *widget, if (priv->last_visible_node) { - graphene_matrix_t matrix; - - graphene_matrix_init_translate (&matrix, &GRAPHENE_POINT3D_INIT (pos_x, pos_y, 0)); - - gtk_snapshot_push_transform (snapshot, &matrix, "StackUnder"); + gtk_snapshot_offset (snapshot, pos_x, pos_y); gtk_snapshot_append_node (snapshot, priv->last_visible_node); - gtk_snapshot_pop (snapshot); + gtk_snapshot_offset (snapshot, -pos_x, -pos_y); } } @@ -1884,7 +1875,6 @@ gtk_stack_snapshot_slide (GtkWidget *widget, if (priv->last_visible_node) { - graphene_matrix_t matrix; int x, y; int width, height; @@ -1927,10 +1917,9 @@ gtk_stack_snapshot_slide (GtkWidget *widget, else if (gtk_widget_get_valign (priv->last_visible_child->widget) == GTK_ALIGN_CENTER) y -= (priv->last_visible_widget_height - height) / 2; - graphene_matrix_init_translate (&matrix, &GRAPHENE_POINT3D_INIT (x, y, 0)); - gtk_snapshot_push_transform (snapshot, &matrix, "StackSlide"); + gtk_snapshot_offset (snapshot, x, y); gtk_snapshot_append_node (snapshot, priv->last_visible_node); - gtk_snapshot_pop (snapshot); + gtk_snapshot_offset (snapshot, -x, -y); } gtk_widget_snapshot_child (widget, -- 2.30.2